Telegram Group & Telegram Channel
⚙️ `[EnumeratorCancellation]` в C# — критически важный атрибут для корректной отмены в `IAsyncEnumerable`

В .NET асинхронные итераторы (`IAsyncEnumerable<T>`) стали мощным инструментом для потоковой обработки данных. Но если вы используете CancellationToken без специального атрибута [EnumeratorCancellation], ваш код может вести себя некорректно и утекать ресурсы. Разберёмся подробно.

⚠️ Проблема: токен есть, но он бесполезен

Допустим, вы пишете такой метод:


public async IAsyncEnumerable<string> FetchItems(CancellationToken cancellationToken)
{
foreach (var id in ids)
{
var item = await GetDataAsync(id);
yield return item;
}
}


Выглядит нормально, но есть подвох: при отмене токен не передаётся в `MoveNextAsync()`, то есть итерация может продолжаться, даже если вызвавшая сторона уже вызвала cancellationToken.Cancel().

💣 Последствия

• Фоновая загрузка продолжается после отмены
• Зависшие соединения, неосвобождённые ресурсы
• Непредсказуемое поведение в await foreach
• Сложные баги и плохая отзывчивость приложений

Решение: [EnumeratorCancellation]

Правильно будет вот так:


public async IAsyncEnumerable<string> FetchItems(
[EnumeratorCancellation] CancellationToken cancellationToken)
{
await foreach (var item in LoadFromDb().WithCancellation(cancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
yield return item;
}
}


📌 Атрибут [EnumeratorCancellation] сообщает компилятору, что токен должен быть передан в реализацию `MoveNextAsync()` итератора. Без этого атрибута токен проигнорируется.

🧪 Как проверить


var cts = new CancellationTokenSource();
await foreach (var item in FetchItems(cts.Token))
{
if (item == "stop") cts.Cancel();
}


Если метод реализован без [EnumeratorCancellation], цикл может не остановиться.
Если с атрибутом — отмена сработает как положено, и итерация завершится немедленно.

🛠 Best Practices

Всегда используйте [EnumeratorCancellation], если метод IAsyncEnumerable<T> принимает CancellationToken
Внутри итератора:
- Вызывайте ThrowIfCancellationRequested()
- Оборачивайте вложенные await foreach или асинхронные методы в .WithCancellation(token)
Не используйте токен «для галочки» — он должен влиять на поведение итератора
Добавляйте юнит‑тесты на отмену, особенно если вы работаете с I/O, API или базами данных

📎 Заключение

Асинхронные итераторы — мощь. Но без [EnumeratorCancellation] ваш токен отмены просто не работает. И это не очевидно, пока вы не столкнётесь с багом, когда ресурсы не освобождаются, или цикл не завершается.

Одна строка — и вы защищены:


[EnumeratorCancellation] CancellationToken token


📚 Источник: https://bartwullems.blogspot.com/2025/04/asyncenumerable-in-c-importance-of.html

🧠 Если ты пишешь на C# и используешь IAsyncEnumerable — знай: токен без атрибута = фейковая отмена.


📌 Читать

@csharp_1001_notes



tg-me.com/csharp_1001_notes/685
Create:
Last Update:

⚙️ `[EnumeratorCancellation]` в C# — критически важный атрибут для корректной отмены в `IAsyncEnumerable`

В .NET асинхронные итераторы (`IAsyncEnumerable<T>`) стали мощным инструментом для потоковой обработки данных. Но если вы используете CancellationToken без специального атрибута [EnumeratorCancellation], ваш код может вести себя некорректно и утекать ресурсы. Разберёмся подробно.

⚠️ Проблема: токен есть, но он бесполезен

Допустим, вы пишете такой метод:


public async IAsyncEnumerable<string> FetchItems(CancellationToken cancellationToken)
{
foreach (var id in ids)
{
var item = await GetDataAsync(id);
yield return item;
}
}


Выглядит нормально, но есть подвох: при отмене токен не передаётся в `MoveNextAsync()`, то есть итерация может продолжаться, даже если вызвавшая сторона уже вызвала cancellationToken.Cancel().

💣 Последствия

• Фоновая загрузка продолжается после отмены
• Зависшие соединения, неосвобождённые ресурсы
• Непредсказуемое поведение в await foreach
• Сложные баги и плохая отзывчивость приложений

Решение: [EnumeratorCancellation]

Правильно будет вот так:


public async IAsyncEnumerable<string> FetchItems(
[EnumeratorCancellation] CancellationToken cancellationToken)
{
await foreach (var item in LoadFromDb().WithCancellation(cancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
yield return item;
}
}


📌 Атрибут [EnumeratorCancellation] сообщает компилятору, что токен должен быть передан в реализацию `MoveNextAsync()` итератора. Без этого атрибута токен проигнорируется.

🧪 Как проверить


var cts = new CancellationTokenSource();
await foreach (var item in FetchItems(cts.Token))
{
if (item == "stop") cts.Cancel();
}


Если метод реализован без [EnumeratorCancellation], цикл может не остановиться.
Если с атрибутом — отмена сработает как положено, и итерация завершится немедленно.

🛠 Best Practices

Всегда используйте [EnumeratorCancellation], если метод IAsyncEnumerable<T> принимает CancellationToken
Внутри итератора:
- Вызывайте ThrowIfCancellationRequested()
- Оборачивайте вложенные await foreach или асинхронные методы в .WithCancellation(token)
Не используйте токен «для галочки» — он должен влиять на поведение итератора
Добавляйте юнит‑тесты на отмену, особенно если вы работаете с I/O, API или базами данных

📎 Заключение

Асинхронные итераторы — мощь. Но без [EnumeratorCancellation] ваш токен отмены просто не работает. И это не очевидно, пока вы не столкнётесь с багом, когда ресурсы не освобождаются, или цикл не завершается.

Одна строка — и вы защищены:


[EnumeratorCancellation] CancellationToken token


📚 Источник: https://bartwullems.blogspot.com/2025/04/asyncenumerable-in-c-importance-of.html

🧠 Если ты пишешь на C# и используешь IAsyncEnumerable — знай: токен без атрибута = фейковая отмена.


📌 Читать

@csharp_1001_notes

BY C# 1001 notes


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/csharp_1001_notes/685

View MORE
Open in Telegram


C 1001 notes Telegram | DID YOU KNOW?

Date: |

How to Use Bitcoin?

n the U.S. people generally use Bitcoin as an alternative investment, helping diversify a portfolio apart from stocks and bonds. You can also use Bitcoin to make purchases, but the number of vendors that accept the cryptocurrency is still limited. Big companies that accept Bitcoin include Overstock, AT&T and Twitch. You may also find that some small local retailers or certain websites take Bitcoin, but you’ll have to do some digging. That said, PayPal has announced that it will enable cryptocurrency as a funding source for purchases this year, financing purchases by automatically converting crypto holdings to fiat currency for users. “They have 346 million users and they’re connected to 26 million merchants,” says Spencer Montgomery, founder of Uinta Crypto Consulting. “It’s huge.”

The Singapore stock market has alternated between positive and negative finishes through the last five trading days since the end of the two-day winning streak in which it had added more than a dozen points or 0.4 percent. The Straits Times Index now sits just above the 3,060-point plateau and it's likely to see a narrow trading range on Monday.

C 1001 notes from us


Telegram C# 1001 notes
FROM USA